//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_OPENGL_ENUMS_H
#define _UX_OPENGL_ENUMS_H

#include "Enums.h"
#include "../GL/opengl.h"

namespace Engine
{

// ------------------------- GL Object Type ---------------------- //

namespace gl_object
{
	enum	type	: uint8
	{
		UNKNOWN		= 0,
		BUFFER,				// VBO, IBO, ...
		TEXTURE,
		VERTEX_ARRAY,
		QUERY,
		SYNC,
		SAMPLER,
		SHADER,
		PROGRAM,
		PROGRAM_PIPELINE,
		FRAMEBUFFER,
		RENDERBUFFER,
		TRANSFORM_FEEDBACK,
	};
}
UX_ENUM_META_OBJECT( gl_object::type );


// ------------------------ Buffer Targets ----------------------- //

namespace gl_buffer
{
	enum	type	: GLenum_t
	{
		ARRAY				= GL_ARRAY_BUFFER,
		ATOMIC_COUNTER		= GL_ATOMIC_COUNTER_BUFFER,
		COPY_READ			= GL_COPY_READ_BUFFER,
		COPY_WRITE			= GL_COPY_WRITE_BUFFER,
		DRAW_INDIRECT		= GL_DRAW_INDIRECT_BUFFER,
		ELEMENT_ARRAY		= GL_ELEMENT_ARRAY_BUFFER,
		PIXEL_PACK			= GL_PIXEL_PACK_BUFFER,
		PIXEL_UNPACK		= GL_PIXEL_UNPACK_BUFFER,
		TEXTURE				= GL_TEXTURE_BUFFER,
		TRANSFORM_FEEDBACK	= GL_TRANSFORM_FEEDBACK_BUFFER,
		UNIFORM				= GL_UNIFORM_BUFFER,
		_INIT				= 0,
		_UNKNOWN			= 0,
	};
}
UX_ENUM_META_OBJECT( gl_buffer::type );


// ------------------------- Query Targets ----------------------- //

namespace gl_query
{
	enum	type	: GLenum_t
	{
		SAMPLES_PASSED							= GL_SAMPLES_PASSED,
		ANY_SAMPLES_PASSED						= GL_ANY_SAMPLES_PASSED,
		TIME_ELAPSED							= GL_TIME_ELAPSED,
		TIMESTAMP								= GL_TIMESTAMP,
		PRIMITIVES_GENERATED					= GL_PRIMITIVES_GENERATED,
		TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN	= GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
		_INIT									= 0,
	};
}
UX_ENUM_META_OBJECT( gl_query::type );


// ---------------------- Conditional Render Mode ---------------- //

namespace gl_cond_render
{
	enum	type	: GLenum_t
	{
		QUERY_WAIT					= GL_QUERY_WAIT,
		QUERY_NO_WAIT				= GL_QUERY_NO_WAIT,
		QUERY_BY_REGION_WAIT		= GL_QUERY_BY_REGION_WAIT,
		QUERY_BY_REGION_NO_WAIT		= GL_QUERY_BY_REGION_NO_WAIT,
		_INIT						= 0,
	};
}
UX_ENUM_META_OBJECT( gl_cond_render::type );


// ------------------------ Cube Map Face ------------------------ //

namespace gl_cube_face
{
	enum	type	: GLenum_t
	{
		POSITIVE_X	= GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		NEGATIVE_X	= GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		POSITIVE_Y	= GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		NEGATIVE_Y	= GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		POSITIVE_Z	= GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		NEGATIVE_Z	= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
		_FIRST		= POSITIVE_X,
		_LAST		= NEGATIVE_Z,
		_INIT		= _FIRST,
		_UNKNOWN	= 0,
	};

	UX_ENUM_ADD_OPERATIONS( type, GLenum_t )
}
UX_ENUM_META_OBJECT( gl_cube_face::type );


// ------------------------ Texture Targets ---------------------- //

namespace gl_texture
{
	enum	type	: GLenum_t
	{
		TEXTURE_1D						= GL_TEXTURE_1D,
		TEXTURE_2D						= GL_TEXTURE_2D,
		TEXTURE_3D						= GL_TEXTURE_3D,
		TEXTURE_CUBE_MAP				= GL_TEXTURE_CUBE_MAP,
		TEXTURE_1D_ARRAY				= GL_TEXTURE_1D_ARRAY,
		TEXTURE_2D_ARRAY				= GL_TEXTURE_2D_ARRAY,
		TEXTURE_2D_MULTISAMPLE			= GL_TEXTURE_2D_MULTISAMPLE,
		TEXTURE_2D_MULTISAMPLE_ARRAY	= GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
		TEXTURE_CUBE_MAP_ARRAY			= GL_TEXTURE_CUBE_MAP_ARRAY,
		TEXTURE_BUFFER					= GL_TEXTURE_BUFFER,
		TEXTURE_RECTANGLE				= GL_TEXTURE_RECTANGLE,
		_INIT							= TEXTURE_2D,
		_UNKNOWN						= 0,

		// for creating CLimage //
		_CUBEFACE_POSITIVE_X			= GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		_CUBEFACE_NEGATIVE_X			= GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		_CUBEFACE_POSITIVE_Y			= GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		_CUBEFACE_NEGATIVE_Y			= GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
		_CUBEFACE_POSITIVE_Z			= GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		_CUBEFACE_NEGATIVE_Z			= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
		_CUBEFACE_FIRST					= _CUBEFACE_POSITIVE_X,
		_CUBEFACE_LAST					= _CUBEFACE_NEGATIVE_Z,
	};

	inline gl_cube_face::type ToCubeFace(type t)
	{
		ASSERT( t >= _CUBEFACE_FIRST && t <= _CUBEFACE_LAST );
		return (gl_cube_face::type)t;
	}

	UX_ENUM_ADD_OPERATIONS( type, GLenum_t )
}
UX_ENUM_META_OBJECT( gl_texture::type );


// ------------------------ Draw Buffer -------------------------- //

namespace gl_draw_buffer
{
	enum	type	: GLenum_t
	{
		NONE				= GL_NONE,
		FRONT_LEFT			= GL_FRONT_LEFT,
		FRONT_RIGHT			= GL_FRONT_RIGHT,
		BACK_LEFT			= GL_BACK_LEFT,
		BACK_RIGHT			= GL_BACK_RIGHT,
		FRONT				= GL_FRONT,
		BACK				= GL_BACK,
		LEFT				= GL_LEFT,
		RIGHT				= GL_RIGHT,
		FRONT_AND_BACK		= GL_FRONT_AND_BACK,
		_INIT				= NONE,
		_UNKNOWN			= type(-1),
	};
}
UX_ENUM_META_OBJECT( gl_draw_buffer::type );


// --------------------- Framebuffer Targets --------------------- //

namespace gl_fbo_target
{
	enum	type	: GLenum_t
	{
		FRAMEBUFFER			= GL_FRAMEBUFFER,
		DRAW_FRAMEBUFFER	= GL_DRAW_FRAMEBUFFER,
		READ_FRAMEBUFFER	= GL_READ_FRAMEBUFFER,
		_INIT				= FRAMEBUFFER,
		_UNKNOWN			= 0,
	};
}
UX_ENUM_META_OBJECT( gl_fbo_target::type );


// ------------------------ Primitive Types ---------------------- //

namespace gl_primitive
{
	enum	type	: GLenum_t
	{
		POINT						= GL_POINTS,
		LINE						= GL_LINES,
		LINE_LOOP					= GL_LINE_LOOP,
		LINE_STRIP					= GL_LINE_STRIP,
		TRIANGLE					= GL_TRIANGLES,
		TRIANGLE_STRIP				= GL_TRIANGLE_STRIP,
		TRIANGLE_FAN				= GL_TRIANGLE_FAN,
		LINE_STRIP_ADJACENCY		= GL_LINE_STRIP_ADJACENCY,
		LINE_ADJACENCY				= GL_LINES_ADJACENCY,
		TRIANGLE_STRIP_ADJACENCY	= GL_TRIANGLE_STRIP_ADJACENCY,
		TRIANGLE_ADJACENCY			= GL_TRIANGLES_ADJACENCY,
		//QUADS						= GL_QUADS,
		//QUAD_STRIP				= GL_QUAD_STRIP,
		//POLYGON					= GL_POLYGON,
		PATCH						= GL_PATCHES,
		_INIT						= TRIANGLE,
		_UNKNOWN					= 0,
	};
}
UX_ENUM_META_OBJECT( gl_primitive::type );


// ------------------------ Blend Equation ----------------------- //

namespace gl_blend_equation
{
	enum	type	: GLenum_t
	{
		ADD					= GL_FUNC_ADD,				// S+D
		SUB					= GL_FUNC_SUBTRACT,			// S-D
		REV_SUB				= GL_FUNC_REVERSE_SUBTRACT,	// D-S
		MIN					= GL_MIN,					// min(S,D)
		MAX					= GL_MAX,					// max(S,D)
		_INIT				= ADD,
		_UNKNOWN			= 0,
	};
}
UX_ENUM_META_OBJECT( gl_blend_equation::type );


// ------------------------- Blend Func -------------------------- //

namespace gl_blend_func
{
	enum	type	: GLenum_t
	{
		ZERO						= GL_ZERO,
		ONE							= GL_ONE,
		SRC_COLOR					= GL_SRC_COLOR,
		ONE_MINUS_SRC_COLOR			= GL_ONE_MINUS_SRC_COLOR,
		DST_COLOR					= GL_DST_COLOR,
		ONE_MINUS_DST_COLOR			= GL_ONE_MINUS_DST_COLOR,
		SRC_ALPHA					= GL_SRC_ALPHA,
		ONE_MINUS_SRC_ALPHA			= GL_ONE_MINUS_SRC_ALPHA,
		DST_ALPHA					= GL_DST_ALPHA,
		ONE_MINUS_DST_ALPHA			= GL_ONE_MINUS_DST_ALPHA,
		CONST_COLOR					= GL_CONSTANT_COLOR,
		ONE_MINUS_CONST_COLOR		= GL_ONE_MINUS_CONSTANT_COLOR,
		CONST_ALPHA					= GL_CONSTANT_ALPHA,
		ONE_MINUS_CONST_ALPHA		= GL_ONE_MINUS_CONSTANT_ALPHA,
		SRC_ALPHA_SATURATE			= GL_SRC_ALPHA_SATURATE,
		SRC1_COLOR					= GL_SRC1_COLOR,
		SRC1_ALPHA					= GL_SRC1_ALPHA,
		ONE_MINUS_SRC1_COLOR		= GL_ONE_MINUS_SRC1_COLOR,
		ONE_MINUS_SRC1_ALPHA		= GL_ONE_MINUS_SRC1_ALPHA,
		_INIT						= ZERO,
		_UNKNOWN					= type(-1),
	};
}
UX_ENUM_META_OBJECT( gl_blend_func::type );


// ------------------------ Compare Mode ------------------------- //

namespace gl_compare_mode
{
	enum	type	: GLenum_t
	{
		NEVER		= GL_NEVER,		// false
		LESS		= GL_LESS,		// <
		EQUAL		= GL_EQUAL,		// ==
		LEQUAL		= GL_LEQUAL,	// <=
		GREATER		= GL_GREATER,	// >
		NOTEQUAL	= GL_NOTEQUAL,	// !=
		GEQUAL		= GL_GEQUAL,	// >=
		ALWAYS		= GL_ALWAYS,	// true
		_INIT		= LESS,
		_UNKNOWN	= 0,
	};
}
UX_ENUM_META_OBJECT( gl_compare_mode::type );


// ------------------------- Usage Mode -------------------------- //

namespace gl_usage
{
	enum	type	: GLenum_t
	{
		STREAM_DRAW		= GL_STREAM_DRAW,
		STREAM_READ		= GL_STREAM_READ,
		STREAM_COPY		= GL_STREAM_COPY,
		STATIC_DRAW		= GL_STATIC_DRAW,
		STATIC_READ		= GL_STATIC_READ,
		STATIC_COPY		= GL_STATIC_COPY,
		DYNAMIC_DRAW	= GL_DYNAMIC_DRAW,
		DYNAMIC_READ	= GL_DYNAMIC_READ,
		DYNAMIC_COPY	= GL_DYNAMIC_COPY,
		_INIT			= STATIC_DRAW,
		_UNKNOWN		= 0,
	};
}
UX_ENUM_META_OBJECT( gl_usage::type );


// ----------------------- Front Face ---------------------------- //

namespace gl_front_face
{
	enum	type	: GLenum_t
	{
		CW		= GL_CW,
		CCW		= GL_CCW,
		_INIT	= CCW,
	};
}
UX_ENUM_META_OBJECT( gl_front_face::type );


// ------------------------ Cull Face ---------------------------- //

namespace gl_cull_face
{
	enum	type	: GLenum_t
	{
		FRONT				= GL_FRONT,
		BACK				= GL_BACK,
		FRONT_AND_BACK		= GL_FRONT_AND_BACK,
		_INIT				= BACK,
	};
}
UX_ENUM_META_OBJECT( gl_cull_face::type );


// ------------------ Enable / Disable Flags --------------------- //

namespace gl_state
{
	enum	type	: GLenum_t
	{
		BLEND						= GL_BLEND,
		CLIP_DISTANCE0				= GL_CLIP_DISTANCE0,
		CLIP_DISTANCE1				= GL_CLIP_DISTANCE1,
		CLIP_DISTANCE2				= GL_CLIP_DISTANCE2,
		CLIP_DISTANCE3				= GL_CLIP_DISTANCE3,
		CLIP_DISTANCE4				= GL_CLIP_DISTANCE4,
		CLIP_DISTANCE5				= GL_CLIP_DISTANCE5,
		CLIP_DISTANCE6				= GL_CLIP_DISTANCE6,
		CLIP_DISTANCE7				= GL_CLIP_DISTANCE7,
		COLOR_LOGIC_OP				= GL_COLOR_LOGIC_OP,
		CULL_FACE					= GL_CULL_FACE,
		DEPTH_CLAMP					= GL_DEPTH_CLAMP,
		DEPTH_TEST					= GL_DEPTH_TEST,
		DITHER						= GL_DITHER,
		FRAMEBUFFER_SRGB			= GL_FRAMEBUFFER_SRGB,
		LINE_SMOOTH					= GL_LINE_SMOOTH,
		MULTISAMPLE					= GL_MULTISAMPLE,
		POLYGON_OFFSET_FILL			= GL_POLYGON_OFFSET_FILL,
		POLYGON_OFFSET_LINE			= GL_POLYGON_OFFSET_LINE,
		POLYGON_OFFSET_POINT		= GL_POLYGON_OFFSET_POINT,
		POLYGON_SMOOTH				= GL_POLYGON_SMOOTH,
		PRIMITIVE_RESTART			= GL_PRIMITIVE_RESTART,
		SAMPLE_ALPHA_TO_COVERAGE	= GL_SAMPLE_ALPHA_TO_COVERAGE,
		SAMPLE_ALPHA_TO_ONE			= GL_SAMPLE_ALPHA_TO_ONE,
		SAMPLE_COVERAGE				= GL_SAMPLE_COVERAGE,
		SAMPLE_SHADING				= GL_SAMPLE_SHADING,
		SAMPLE_MASK					= GL_SAMPLE_MASK,
		SCISSOR_TEST				= GL_SCISSOR_TEST,
		STENCIL_TEST				= GL_STENCIL_TEST,
		TEXTURE_CUBE_MAP_SEAMLESS	= GL_TEXTURE_CUBE_MAP_SEAMLESS,
		PROGRAM_POINT_SIZE			= GL_PROGRAM_POINT_SIZE,
		_INIT						= 0,
	};
}
UX_ENUM_META_OBJECT( gl_state::type );


// ------------------------ Vertex Type -------------------------- //

namespace gl_vertex
{
	enum	type	: GLenum_t
	{
		BYTE						= GL_BYTE,
		UBYTE						= GL_UNSIGNED_BYTE,
		SHORT						= GL_SHORT,
		USHORT						= GL_UNSIGNED_SHORT,
		INT							= GL_INT,
		UINT						= GL_UNSIGNED_INT,
		HALF						= GL_HALF_FLOAT,
		FLOAT						= GL_FLOAT,
		DOUBLE						= GL_DOUBLE,
		FIXED						= GL_FIXED,
		INT_2_10_10_10_REV			= GL_INT_2_10_10_10_REV,
		UNSIGNED_INT_2_10_10_10_REV	= GL_UNSIGNED_INT_2_10_10_10_REV,
		_INIT						= FLOAT,
	};
}
UX_ENUM_META_OBJECT( gl_vertex::type );


// ------------------------- Index Type -------------------------- //

namespace gl_index
{
	enum	type	: GLenum_t
	{
		UBYTE			= GL_UNSIGNED_BYTE,
		USHORT			= GL_UNSIGNED_SHORT,
		UINT			= GL_UNSIGNED_INT,

		UINT_8			= UBYTE,
		UINT_16			= USHORT,
		UINT_32			= UINT,
		
		_INIT			= UINT,
		_UNKNOWN		= 0,
	};
}
UX_ENUM_META_OBJECT( gl_index::type );


// ------------------------- FBO Attach -------------------------- //

namespace gl_fbo_attach
{
	enum	type	: GLenum_t
	{
		DEPTH		= GL_DEPTH_ATTACHMENT,
		STENCIL		= GL_STENCIL_ATTACHMENT,
		COLOR0		= GL_COLOR_ATTACHMENT0,
		COLOR1		= GL_COLOR_ATTACHMENT1,
		COLOR2		= GL_COLOR_ATTACHMENT2,
		COLOR3		= GL_COLOR_ATTACHMENT3,
		COLOR4		= GL_COLOR_ATTACHMENT4,
		COLOR5		= GL_COLOR_ATTACHMENT5,
		COLOR6		= GL_COLOR_ATTACHMENT6,
		COLOR7		= GL_COLOR_ATTACHMENT7,
		COLOR8		= GL_COLOR_ATTACHMENT8,
		COLOR9		= GL_COLOR_ATTACHMENT9,
		COLOR10		= GL_COLOR_ATTACHMENT10,
		COLOR11		= GL_COLOR_ATTACHMENT11,
		COLOR12		= GL_COLOR_ATTACHMENT12,
		COLOR13		= GL_COLOR_ATTACHMENT13,
		COLOR14		= GL_COLOR_ATTACHMENT14,
		COLOR15		= GL_COLOR_ATTACHMENT15,
		_INIT		= 0,
	};
}
UX_ENUM_META_OBJECT( gl_fbo_attach::type );


// --------------------------- Logic Op -------------------------- //

namespace gl_logic_op
{
	enum	type	: GLenum_t
	{
		CLEAR				= GL_CLEAR,
		SET					= GL_SET,
		COPY				= GL_COPY,
		COPY_INVERTED		= GL_COPY_INVERTED,
		NOOP				= GL_NOOP,
		INVERT				= GL_INVERT,
		AND					= GL_AND,
		NAND				= GL_NAND,
		OR					= GL_OR,
		NOR					= GL_NOR,
		XOR					= GL_XOR,
		EQUIV				= GL_EQUIV,
		AND_REVERSE			= GL_AND_REVERSE,
		AND_INVERTED		= GL_AND_INVERTED,
		OR_REVERSE			= GL_OR_REVERSE,
		OR_INVERTED			= GL_OR_INVERTED,
		_INIT				= COPY,
	};
}
UX_ENUM_META_OBJECT( gl_logic_op::type );


// ------------------------- Uniform Type ------------------------ //

namespace gl_uniform
{
	enum	type	: GLenum_t
	{
		_UNKNOWN				= 0,

		// Bool //
		BOOL					= GL_BOOL,
		BOOL_VEC2				= GL_BOOL_VEC2,
		BOOL_VEC3				= GL_BOOL_VEC3,
		BOOL_VEC4				= GL_BOOL_VEC4,
		
		// Float //
		FLOAT					= GL_FLOAT,
		FLOAT_VEC2				= GL_FLOAT_VEC2,
		FLOAT_VEC3				= GL_FLOAT_VEC3,
		FLOAT_VEC4				= GL_FLOAT_VEC4,
		FLOAT_MAT2				= GL_FLOAT_MAT2,
		FLOAT_MAT3				= GL_FLOAT_MAT3,
		FLOAT_MAT4				= GL_FLOAT_MAT4,
		FLOAT_MAT2x3			= GL_FLOAT_MAT2x3,
		FLOAT_MAT2x4			= GL_FLOAT_MAT2x4,
		FLOAT_MAT3x2			= GL_FLOAT_MAT3x2,
		FLOAT_MAT3x4			= GL_FLOAT_MAT3x4,
		FLOAT_MAT4x2			= GL_FLOAT_MAT4x2,
		FLOAT_MAT4x3			= GL_FLOAT_MAT4x3,

		// Double //
		DOUBLE					= GL_DOUBLE,
		DOUBLE_VEC2				= GL_DOUBLE_VEC2,
		DOUBLE_VEC3				= GL_DOUBLE_VEC3,
		DOUBLE_VEC4				= GL_DOUBLE_VEC4,
		DOUBLE_MAT2				= GL_DOUBLE_MAT2,
		DOUBLE_MAT3				= GL_DOUBLE_MAT3,
		DOUBLE_MAT4				= GL_DOUBLE_MAT4,
		DOUBLE_MAT2x3			= GL_DOUBLE_MAT2x3,
		DOUBLE_MAT2x4			= GL_DOUBLE_MAT2x4,
		DOUBLE_MAT3x2			= GL_DOUBLE_MAT3x2,
		DOUBLE_MAT3x4			= GL_DOUBLE_MAT3x4,
		DOUBLE_MAT4x2			= GL_DOUBLE_MAT4x2,
		DOUBLE_MAT4x3			= GL_DOUBLE_MAT4x3,

		// Int //
		INT						= GL_INT,
		INT_VEC2				= GL_INT_VEC2,
		INT_VEC3				= GL_INT_VEC3,
		INT_VEC4				= GL_INT_VEC4,

		// UInt //
		UINT					= GL_UNSIGNED_INT,
		UINT_VEC2				= GL_UNSIGNED_INT_VEC2,
		UINT_VEC3				= GL_UNSIGNED_INT_VEC3,
		UINT_VEC4				= GL_UNSIGNED_INT_VEC4,


		// Samplers //
		SAMPLER_1D						= GL_SAMPLER_1D,
		SAMPLER_2D						= GL_SAMPLER_2D,
		SAMPLER_3D						= GL_SAMPLER_3D,
		SAMPLER_CUBE_MAP				= GL_SAMPLER_CUBE,
		SAMPLER_1D_SHADOW				= GL_SAMPLER_1D_SHADOW,
		SAMPLER_2D_SHADOW				= GL_SAMPLER_2D_SHADOW,
		SAMPLER_2D_MS					= GL_SAMPLER_2D_MULTISAMPLE,
		SAMPLER_2D_MS_ARRAY				= GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
		SAMPLER_CUBE_MAP_ARRAY			= GL_SAMPLER_CUBE_MAP_ARRAY_ARB,
		SAMPLER_CUBE_MAP_ARRAY_SHADOW	= GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB,
		SAMPLER_1D_ARRAY				= GL_SAMPLER_1D_ARRAY,
		SAMPLER_2D_ARRAY				= GL_SAMPLER_2D_ARRAY,
		SAMPLER_1D_ARRAY_SHADOW			= GL_SAMPLER_1D_ARRAY_SHADOW,
		SAMPLER_2D_ARRAY_SHADOW			= GL_SAMPLER_2D_ARRAY_SHADOW,
		SAMPLER_CUBE_MAP_SHADOW			= GL_SAMPLER_CUBE_SHADOW,
		SAMPLER_BUFFER					= GL_SAMPLER_BUFFER,
		SAMPLER_2D_RECT					= GL_SAMPLER_2D_RECT,
		SAMPLER_2D_RECT_SHADOW			= GL_SAMPLER_2D_RECT_SHADOW,
		INT_SAMPLER_1D					= GL_INT_SAMPLER_1D,
		INT_SAMPLER_2D					= GL_INT_SAMPLER_2D,
		INT_SAMPLER_3D					= GL_INT_SAMPLER_3D,
		INT_SAMPLER_CUBE_MAP			= GL_INT_SAMPLER_CUBE,
		INT_SAMPLER_1D_ARRAY			= GL_INT_SAMPLER_1D_ARRAY,
		INT_SAMPLER_2D_ARRAY			= GL_INT_SAMPLER_2D_ARRAY,
		INT_SAMPLER_BUFFER				= GL_INT_SAMPLER_BUFFER,
		INT_SAMPLER_2D_RECT				= GL_INT_SAMPLER_2D_RECT,
		INT_SAMPLER_CUBE_MAP_ARRAY		= GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB,
		INT_SAMPLER_2D_MS				= GL_INT_SAMPLER_2D_MULTISAMPLE,
		INT_SAMPLER_2D_MS_ARRAY			= GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
		UINT_SAMPLER_1D					= GL_UNSIGNED_INT_SAMPLER_1D,
		UINT_SAMPLER_2D					= GL_UNSIGNED_INT_SAMPLER_2D,
		UINT_SAMPLER_3D					= GL_UNSIGNED_INT_SAMPLER_3D,
		UINT_SAMPLER_CUBE_MAP			= GL_UNSIGNED_INT_SAMPLER_CUBE,
		UINT_SAMPLER_1D_ARRAY			= GL_UNSIGNED_INT_SAMPLER_1D_ARRAY,
		UINT_SAMPLER_2D_ARRAY			= GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,
		UINT_SAMPLER_BUFFER				= GL_UNSIGNED_INT_SAMPLER_BUFFER,
		UINT_SAMPLER_2D_RECT			= GL_UNSIGNED_INT_SAMPLER_2D_RECT,
		UINT_SAMPLER_CUBE_MAP_ARRAY		= GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB,
		UINT_SAMPLER_2D_MS				= GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
		UINT_SAMPLER_2D_MS_ARRAY		= GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,

		// Images //
		IMAGE_1D					= GL_IMAGE_1D,
		IMAGE_2D					= GL_IMAGE_2D,
		IMAGE_3D					= GL_IMAGE_3D,
		IMAGE_2D_RECT				= GL_IMAGE_2D_RECT,
		IMAGE_CUBE					= GL_IMAGE_CUBE,
		IMAGE_BUFFER				= GL_IMAGE_BUFFER,
		IMAGE_1D_ARRAY				= GL_IMAGE_1D_ARRAY,
		IMAGE_2D_ARRAY				= GL_IMAGE_2D_ARRAY,
		IMAGE_CUBE_MAP_ARRAY		= GL_IMAGE_CUBE_MAP_ARRAY,
		IMAGE_2D_MS					= GL_IMAGE_2D_MULTISAMPLE,
		IMAGE_2D_MS_ARRAY			= GL_IMAGE_2D_MULTISAMPLE_ARRAY,
		INT_IMAGE_1D				= GL_INT_IMAGE_1D,
		INT_IMAGE_2D				= GL_INT_IMAGE_2D,
		INT_IMAGE_3D				= GL_INT_IMAGE_3D,
		INT_IMAGE_2D_RECT			= GL_INT_IMAGE_2D_RECT,
		INT_IMAGE_CUBE				= GL_INT_IMAGE_CUBE,
		INT_IMAGE_BUFFER			= GL_INT_IMAGE_BUFFER,
		INT_IMAGE_1D_ARRAY			= GL_INT_IMAGE_1D_ARRAY,
		INT_IMAGE_2D_ARRAY			= GL_INT_IMAGE_2D_ARRAY,
		INT_IMAGE_CUBE_MAP_ARRAY	= GL_INT_IMAGE_CUBE_MAP_ARRAY,
		INT_IMAGE_2D_MS				= GL_INT_IMAGE_2D_MULTISAMPLE,
		INT_IMAGE_2D_MS_ARRAY		= GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
		UINT_IMAGE_1D				= GL_UNSIGNED_INT_IMAGE_1D,
		UINT_IMAGE_2D				= GL_UNSIGNED_INT_IMAGE_2D,
		UINT_IMAGE_3D				= GL_UNSIGNED_INT_IMAGE_3D,
		UINT_IMAGE_2D_RECT			= GL_UNSIGNED_INT_IMAGE_2D_RECT,
		UINT_IMAGE_CUBE				= GL_UNSIGNED_INT_IMAGE_CUBE,
		UINT_IMAGE_BUFFER			= GL_UNSIGNED_INT_IMAGE_BUFFER,
		UINT_IMAGE_1D_ARRAY			= GL_UNSIGNED_INT_IMAGE_1D_ARRAY,
		UINT_IMAGE_2D_ARRAY			= GL_UNSIGNED_INT_IMAGE_2D_ARRAY,
		UINT_IMAGE_CUBE_MAP_ARRAY	= GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY,
		UINT_IMAGE_2D_MS			= GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,
		UINT_IMAGE_2D_MS_ARRAY		= GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
	};
}
UX_ENUM_META_OBJECT( gl_uniform::type );


// ------------------------ Map Buffer Flags --------------------- //

namespace gl_map_buffer
{
	enum	type	: uint16
	{
		READ				= GL_MAP_READ_BIT,
		WRITE				= GL_MAP_WRITE_BIT,

		// for MapBufferRange only //
		INVALIDATE_RANGE	= GL_MAP_INVALIDATE_RANGE_BIT,
		INVALIDATE_BUFFER	= GL_MAP_INVALIDATE_BUFFER_BIT,
		FLUSH_EXPLICIT		= GL_MAP_FLUSH_EXPLICIT_BIT,
		UNSYNCHRONIZED		= GL_MAP_UNSYNCHRONIZED_BIT,

		_INIT				= READ,
		_UNKNOWN			= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type, uint16 )
}
UX_ENUM_META_OBJECT( gl_map_buffer::type );


// ------------------------- Attrib Mask ------------------------- //

namespace gl_attrib_mask
{
	enum	type	: uint32
	{
		DEPTH		= GL_DEPTH_BUFFER_BIT,
		STENCIL		= GL_STENCIL_BUFFER_BIT,
		COLOR		= GL_COLOR_BUFFER_BIT,
		ALL			= 0xFFFFFFFF,
		_INIT		= COLOR,
		_UNKNOWN	= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type, uint32 )
}
UX_ENUM_META_OBJECT( gl_attrib_mask::type );


// ------------------------ Stencil Op --------------------------- //

namespace gl_stencil_op
{
	enum	type	: GLenum_t
	{
		KEEP		= GL_KEEP,
		ZERO		= GL_ZERO,
		REPLACE		= GL_REPLACE,
		INCR		= GL_INCR,
		INCR_WRAP	= GL_INCR_WRAP,
		DECR		= GL_DECR,
		DECR_WRAP	= GL_DECR_WRAP,
		INVERT		= GL_INVERT,
		_INIT		= KEEP,
		_UNKNOWN	= 0,
	};
}
UX_ENUM_META_OBJECT( gl_stencil_op::type );


// ----------------------- Memory Barrier ------------------------ //

namespace gl_memory_barrier
{
	enum	type	: uint32
	{
		VERTEX_ATTRIB_ARRAY	= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT,
		ELEMENT_ARRAY		= GL_ELEMENT_ARRAY_BARRIER_BIT,
		UNIFORM				= GL_UNIFORM_BARRIER_BIT,
		TEXTURE_FETCH		= GL_TEXTURE_FETCH_BARRIER_BIT,
		SHADER_IMAGE_ACCESS	= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,
		COMMAND				= GL_COMMAND_BARRIER_BIT,
		PIXEL_BUFFER		= GL_PIXEL_BUFFER_BARRIER_BIT,
		TEXTURE_UPDATE		= GL_TEXTURE_UPDATE_BARRIER_BIT,
		BUFFER_UPDATE		= GL_BUFFER_UPDATE_BARRIER_BIT,
		FRAMEBUFFER			= GL_FRAMEBUFFER_BARRIER_BIT,
		TRANSFORM_FEEDBACK	= GL_TRANSFORM_FEEDBACK_BARRIER_BIT,
		ATOMIC_COUNTER		= GL_ATOMIC_COUNTER_BARRIER_BIT,
		ALL					= GL_ALL_BARRIER_BITS,
		_INIT				= 0,
		_UNKNOWN			= 0,
	};

	UX_ENUM_BIT_OPERATIONS( type, uint32 )
}
UX_ENUM_META_OBJECT( gl_memory_barrier::type );


// ------------------------ Polygon Mode ------------------------- //

namespace gl_polygon_mode
{
	enum	type :	GLenum_t
	{
		POINT	= GL_POINT,
		LINE	= GL_LINE,
		FILL	= GL_FILL,
	};
}


// ------------------------- Access Type ------------------------- //

namespace gl_access
{
	enum	type :	GLenum_t
	{
		READ		= GL_READ_ONLY,
		WRITE		= GL_WRITE_ONLY,
		READ_WRITE	= GL_READ_WRITE,
	};
}


// -------------------- Internal Image Format -------------------- //

namespace gl_image_ifmt
{
	enum	type :	GLenum_t
	{
		RGBA32F			= GL_RGBA32F,
		RGBA16F			= GL_RGBA16F,
		RG32F			= GL_RG32F,
		RG16F			= GL_RG16F,
		R11F_G11F_B10F	= GL_R11F_G11F_B10F,
		R32F			= GL_R32F,
		R16F			= GL_R16F,
		RGBA32UI		= GL_RGBA32UI,
		RGBA16UI		= GL_RGBA16UI,
		RGB10_A2UI		= GL_RGB10_A2UI,
		RGBA8UI			= GL_RGBA8UI,
		RG32UI			= GL_RG32UI,
		RG16UI			= GL_RG16UI,
		RG8UI			= GL_RG8UI,
		R32UI			= GL_R32UI,
		R16UI			= GL_R16UI,
		R8UI			= GL_R8UI,
		RGBA32I			= GL_RGBA32I,
		RGBA16I			= GL_RGBA16I,
		RGBA8I			= GL_RGBA8I,
		RG32I			= GL_RG32I,
		RG16I			= GL_RG16I,
		RG8I			= GL_RG8I,
		R32I			= GL_R32I,
		R16I			= GL_R16I,
		R8I				= GL_R8I,
		RGBA16			= GL_RGBA16,
		RGB10_A2		= GL_RGB10_A2,
		RGBA8			= GL_RGBA8,
		RG16			= GL_RG16,
		RG8				= GL_RG8,
		R16				= GL_R16,
		R8				= GL_R8,
		RGBA16_SNORM	= GL_RGBA16_SNORM,
		RGBA8_SNORM		= GL_RGBA8_SNORM,
		RG16_SNORM		= GL_RG16_SNORM,
		RG8_SNORM		= GL_RG8_SNORM,
		R16_SNORM		= GL_R16_SNORM,
		R8_SNORM		= GL_R8_SNORM,
	};
}

//-------------------------------------------------------------------

}	// Engine

#endif	// _UX_OPENGL_ENUMS_H